<?php /* Copyright 2014 Karl R. Wilcox

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License. */
   
class languageDB extends lexicon {
  // These constants acts as keys into the pattern database
  // Some are also used to indicate the type of modifier
  const OVERALL = 'overall';
  const SPLITS = 'splits';
  const ONFIELDOF = 'onfieldof';
  const SEMICOLON = 'semicolon';
  const COMMA = 'comma';
  const WORD_OF = 'wordof';
  const WORD_ON = 'wordon';
  const WORD_IN = 'wordin';
  const COLOUR = 'colour';
  const BACKREF = 'backref';
  const TREATMENT = 'treament';
  const FUR = 'fur';
  const SEMY = 'semy';
  const GROUP = 'group';
  const PROPER = 'proper';
  const ANDD = 'andd';
  const WITH = 'with';
  const QUARTERED = 'quartered';
  const QUARTERS = 'quarters';
  const COUNTERCHANGE = 'counterchange';
  const QUANTITY = 'amount';
  const NUMBER = 'number';
  const DIVISION_MODS = 'divmods';
  const DIVISION = 'division';
  const LINETYPE = 'linetype';
  const ORIENTATION = 'orientation';
  const ORDINARY = 'ordinary';
  const ORDINARY_PREFIX = 'ordprefix';
  const ORDINARY_MODS = 'ordmods';
  const COLOUR_MODS = 'compony';
  const LINETYPE_PREFIX = 'linepre';
  const LINETYPE_POSTFIX = 'linepost';
  const COTTICE_MODS = 'cotticemods';
  const CHARGE_NOT_ORDINARY = 'chargeconf';
  const ORDINARY_OR_CHARGE = 'ordorchg';
  const ORDINARY_NOT_CHARGE = 'ordinaryconf';
  const CHARGE = 'charge';
  const BETWEEN = 'between';
  const COTTICE = 'cottice';
  const VOIDED = 'voided';
  const CHARGE_WITH = 'chargewith';
  const ARRANGEMENT = 'arrangement';
  const SPECIFIER = 'specifier';
  const LOCATION = 'location';
  const QUANTIFIER = 'quantifier';
  const BUNDLE = 'bundle';
  const CHARGE_PREFIX = 'chargepre';
  const CHARGE_ADJACENT = 'chargeadj';
  const CHARGE_FEATURES = 'chargefeat';
  const CHARGE_MODS = 'chargemod';
  const POSITION = 'position';
  
  public function __construct() {
    $this->language = 'english';
     
    // Each top level element of the patterns array is a named sub-array
    // Each named sub-array represents a particular word category 
    // The sub arrays contain a list of mappings between regular expressions
    // and a "key term". (If there is no key term given, the regex itself
    // is used). The grammar requests a search for a particular word
    // category, and if found, the specific key term is returned.
 
    $this->patterns = array(
      self::OVERALL => array ( 'overall', 'over all', 'over ?all ?the ?# (quarters|quarterings|halves|parts|sections)', 
        'sur le tout', 'all with(in)?', ),
      self::SPLITS => array (
        array ( 'impaled with', 'impaled' ),
        array ( 'dimidiated with', 'dimidiated' ),
      ),
      self::ONFIELDOF => array ( 'on a field ?of' ),
      self::WITH => array ( array ('(with|upon)', 'with' ) ),
      self::BETWEEN => array ( 'between', 'inter', 'within', 'inside', 'surrounded by', 'accompagne' ),
      self::QUARTERED => array (
        array ( 'quartered', 'quartered' ), // Always a marshalling
        array ( 'quarterly', 'quarterly' ), // Could be a marshalling or a division
      ),
      self::QUARTERS => array (
        array ( '(first|1st|i|1|one)', 1 ),
        array ( '(second|2nd|ii|2|two)', 2 ),
        array ( '(third|3rd|iii|3|three)', 3 ),
        array ( '(fourth|4th|iv|iiii|4|four)', 4 ),
        array ( '(fifth|5th|v|5|five)', 5 ),
        array ( '(sixth|6th|vi|6|six)', 6 ),
        array ( '(seventh|7th|vii|7|seven)', 7 ),                                                 
        array ( '(eighth|8th|viii|8|eight)', 8 ),
      ),
      self::SEMICOLON => array ( ';', '\\.' ), // need to escape '.' as this is regex special character
      self::COMMA => array ( ',' ),
      self::WORD_OF => array ( 'of' ),
      self::WORD_ON => array ( 'on' ),
      self::WORD_IN => array ( 'in ?the' ),
      self::ANDD => array ( 
        array ( '(and|&|also)', 'and'), 
        array ( '(and|&) also', 'and'),
        ),
      self::COLOUR => array (
          // basic tinctures (with abbreviations)
          array ( '(gold|or)',  'or'    ),
          array ( 'az(ure)?',  'azure'   ),
          array ( 'vert|sinople', 'vert' ),
          array ( 'gui?(les)?', 'gules'    ),
          array ( 'arg(ent)?', 'argent'  ),
          array ( 'silver', 'argent'  ),
          array ( 'sa(ble)?', 'sable' ),
          array ( 'purp(le|ure)', 'purpure' ),
          // additional tinctures
          'murrey',  'sanguine',  'carnation', 'brunatre', 'cendree',  'rose',  
          array ( 'bis(que)?', 'bis' ),
          array ( 'celestial azure', 'celestial-azure'  ),
          array ( 'bleu celeste', 'celestial-azure'  ),
          array ( 'senois', 'senois' ),
          array ( '(tanned|tenne|tawny)', 'tenne' ),
          'orange',
          // "de" names (for gouttes particularly)
          array ( 'd or', 'or'  ),
          array ( 'd eau', 'argent'  ),
          array ( 'de larmes', 'azure'  ),
          array ( 'de sangu?e?', 'gules' ),
          array ( 'de vin', 'gules'   ),
          array ( 'de poix', 'sable'  ),
          array ( 'd huile',  'vert' ),
          array ( 'd olive',  'vert' ),
          // obsolete names
          'amethyst', 'diamond', 'dragons head', 'dragons tail', 'emerald', 
          'jacinth', 'luna', 'mars', 'pearl', 'ruby', 'sol', 'topaz', 'venus',
          // Named web colors 
          /* comment out from here to disable web colours 
         'alice blue', 'antique white', 'aqua', 'aquamarine', 'beige', 'black', 'blanched almond',  
         'blue', 'blue violet', 'brown', 'burly wood', 'cadet blue', 'chartreuse', 'chocolate',
         'coral', 'cornflower blue', 'cornsilk', 'crimson', 'cyan', 'dark blue', 'dark cyan',
         'dark goldenrod',                                                                  
          array ( 'dark gr(a|e)y', 'dark gray'),
          'dark green',     'dark khaki', 'dark magenta', 'dark olive green', 'dark orange',
          'dark orchid', 'dark red', 'dark salmon', 'dark sea green', 'dark slate blue',  
          array ( 'dark slate gr(a|e)y', 'dark slate gray'),
          'dark turquoise',  'dark violet', 'deep pink', 'deep sky blue',   
          array ( 'dim gr(a|e)y', 'dim gray'),                             
          'dodger blue',  'fire brick', 'floral white', 'forest green', 'fuchsia',
          'gainsboro', 'ghost white', 'gold', 'goldenrod',      
          array ( 'gr(a|e)y', 'gray' ),
          'green', 'green yellow', 'honeydew', 'hot pink', 'indian red', 'indigo',
          'ivory', 'khaki', 'lavender', 'lavender blush', 'lawn green', 'lemon chiffon',
          'light blue', 'light coral', 'light cyan', 'light goldenrod yellow',
          array ( 'light gr(a|e)y', 'light gray' ),
          'light green', 'light pink', 'light salmon', 'light sea green',
          'light sky blue',                     
          array ( 'light slate gr(a|e)y', 'light slate gray'),
          'light steel blue',   'light yellow', 'lime', 'lime green', 'linen', 'magenta',
          'maroon', 'medium aquamarine', 'medium blue', 'medium orchid', 'medium purple',
          'medium sea green', 'medium slate blue', 'medium spring green', 'medium turquoise',
          'medium violet red', 'midnight blue', 'mint cream', 'misty rose', 'moccasin',
          'navajo white', 'navy', 'old lace', 'olive', 'olive drab',                    
          'orange red', 'orchid', 'pale goldenrod', 'pale green', 'pale turquoise',
          'pale violet red', 'papaya whip', 'peach puff', 'peru', 'pink', 'plum',
          'powder blue', 'purple', 'red', 'rosy brown', 'royal blue', 'saddle brown',
          'salmon', 'sandy brown', 'sea green', 'sea shell', 'sienna', 'silver',
          'sky blue', 'slate blue',        
          array ( 'slate gr(a|e)y', 'slate gray'),                 
          'snow', 'spring green', 'steel blue', 'tan', 'teal', 'thistle', 'tomato',
          'turquoise', 'violet', 'wheat', 'white', 'white smoke', 'yellow', 'yellow green',                          
            End comment here */
          ),
        self::BACKREF => array (
            array ( '(like|of|as) the same', 'ofsame'),
            array ( '(like|of|as) the last', 'oflast'),
            array ( '(like|of|as) the field', 'offield'),
            array ( '(like|of|as) the (first|1st)', 'offirst'),
            array ( '(like|of|as) the (second|2nd)', 'ofsecond'),
            array ( '(like|of|as) the (third|3rd)', 'ofthird'),
            array ( '(like|of|as) the (fourth|4th)', 'offourth'),
        ),
        self::TREATMENT => array (
            array ( 'ann?ulett?y',    'annuletty',    ),
            array ( 'bezant(y|e)',  'bezanty', true ),
            array ( 'billett?y',     'billetty',     ),
            array ( '(checky|cheque?y|checkered)', 'checky' ),
            array ( '?billetty counter billetty', 'counter-billetty',),
            array ( 'crusill?[ye]',     'crusilly',     ),
            array ( 'estoill?[ye]',     'estoilly',    ),
            array ( 'fretty',       'fretty',       ),
            array ( '(treille|latticed)',       'latticed',       ), // TODO draw this, see boutell
            array ( 'plumetty',       'plumetty',       ), // TODO draw this, see boutell
            array ( 'go?utty?e?e?',      'goutty',     ),
            array ( 'grillage',     'grillage',     ),
            array ( 'honeycombed',  'honeycombed',  ),
            array ( 'hurty',        'hurty',       true ),
            array ( 'maily',        'maily',        ),
            array ( '(masonn?ed?|muraille)',      'masoned',      ),
            array ( 'mullett?y',    'mulletty',   ),
            array ( 'pap(e|i)l?lonn(y|e)', 'papelonny', ),
            array ( 'platy',        'platy',       true ),
            array ( 'scaly',        'scaly',        ),
            array ( 'sem(e|y) de l(i|y)s', 'seme-de-lys', ),
            array ( 'vair(e|y)',    'vairy',  ),
            array ( 'ai?[qg]ui?lated', 'aquilated' ), // TODO draw this
            array ( 'ferrated', 'ferrated' ), // TODO and this
            array ( 'trefle', 'trefle' ), // TODO and this
            array ( 'verd(e|oy)', 'verdy' ), // TODO and this
            array ( 'barruly wavy', 'barruly-wavy' ), // TODO and this
        ),
        self::FUR => array (
          'ermine',   'erminois', 'erminites', 'pean', 'potent', 'vair', // TODO draw erminites
          array ( 'or ermined sa(ble)?', 'erminois',           ),                      
          array ( 'sa(ble)? ermined or', 'pean',            ),
          array ( 'vair in pale', 'vair-in-pale',    ),
          array ( 'vair en point', 'vair-en-point',   ),
          array ( 'ermines', 'counter-ermine',  ),
          array ( 'counter ermine', 'counter-ermine',  ),
          array ( 'sa(ble)? ermined arg(ent)?', 'counter-ermine',  ),
          array ( 'counter vair', 'counter-vair',    ),
          array ( 'counter potent', 'counter-potent',  ),
          array ( 'potent counter potent', 'potent-counter-potent', ),
        ),
        self::SEMY => array ( '(seme|semy) (de|with|of)', '(aspersed|strewn) with', '(poudre|powdered) with' ),
        self::GROUP => array ( '(both|all|the|his|her|its)',  ),
        self::PROPER => array ( '(proper|ppr)' ),
        self::COUNTERCHANGE => array ( 'interchanged?', 'transmuted', 'counterchanged?', 'countercoloured', 'de l un en l autre' ),
        self::DIVISION => array (
          array ( 'pily',                  'pily',               ),
          array ( 'quarterly',             'quarterly',          ),
          array ( '?party per cross',      'quarterly',          ),
          array ( 'quarterly ?, per fesse?',    'quarterly-per-fess', ),
          array ( 'quarterly ?, per pale',    'quarterly-per-pale', ),
          array ( 'paly bendy',            'paly-bendy',         ),
          array ( 'bendy paly',            'paly-bendy',         ),
          array ( 'pily bendy',            'pily-bendy',         ),
          array ( 'bendy pily',            'pily-bendy',         ),
          array ( 'b[ua]rr?(y|uly) ?sans ?nombre', 'barry',      ),
          array ( 'paly',                  'paly',               ),
          array ( 'chape',                 'chape',              ),
          array ( 'chevronn?(ell)?y',      'chevronny',          ),
          array ( 'chausse',               'chausse',            ),
          array ( 'quarterly quartered',   'gyronny',		 ),
          array ( 'g(i|y)ronny',           'gyronny',            ),
          array ( 'bendy',                 'bendy',              ),
          array ( '?party per fesse?' ,    'per-fess',           ),
          array ( 'parted fesse?wise' ,      'per-fess',           ),
          array ( '?party per pale' ,      'per-pale',           ),
          array ( 'parted palewise' ,      'per-pale',           ),
          array ( '?party per pile' ,      'per-pile',           ),
          array ( 'parted pilewise' ,      'per-pile',           ),
          array ( '?party per pall' ,      'per-pall',           ),
          array ( 'tierced in pairle' ,    'per-pall',           ),
          array ( '?party per chevron' ,   'per-chevron',        ),
          array ( 'parted chevronwise' ,   'per-chevron',        ),
          array ( 'enty' ,   'enty',        ),
          array ( '?party per bend',       'per-bend',           ),
          array ( 'parted bendwise',       'per-bend',           ),
          array ( '?party per saltire' ,   'per-saltire',        ),
          array ( 'parted saltirewise' ,   'per-saltire',        ),
          array ( 'tierced in pale' ,      'tierced-in-pale',    ),
          array ( 'tierced in fesse?' ,      'tierced-in-fess',    ),
          array ( 'tierced in bend' ,      'tierced-in-bend',    ),
          array ( 'tierced in chevron',    'tierced-in-chevron', ),
          array ( 'fusill?y',              'fusily',             ),
          array ( 'fusill?y bendy ?dexter','fusily-bendy',       ),                                     
          array ( 'fusill?y in bend',      'fusily-bendy',       ),
          array ( '(lozengy|masculy)',     'lozengy',            ),
          array ( '?barry bendy ?lozengy' , 'barry-bendy',        ),
          array ( 'barry pily' ,           'barry-pily',         ),
          array ( 'barry indented ?the (one|1) in the other', 'barry-indented-oio',  ),
       ),   
       self::DIVISION_MODS => array ( 
         array ( 'of # ?pieces?', 'ofnum' ),
         ),
       self::QUANTITY => array (
          array ( '(a|an|the)', "1" ),
          ),
       self::NUMBER => array (
          array ( '(1|one)', "1" ),
          array ( '(2|two)', "2" ),
          array ( '(3|three)', "3" ),
          array ( '(4|four)', "4" ),
          array ( '(5|five)', "5" ),
          array ( '(6|six)', "6"  ),
          array ( '(7|seven)', "7" ),
          array ( '(8|eight)', "8" ),
          array ( '(9|nine)', "9" ),
          array ( '(10|ten)', "10" ),
          array ( '(11|eleven)', "11" ),
          array ( '(12|twelve)', "12" ),
          array ( '(13|thirteen)', "13" ),
          array ( '(14|fourteen)', "14" ),
          array ( '(15|fifteen)', "15" ),
          array ( '(16|sixteen)', "16" ),
          array ( '(17|seventeen)', "17" ),
          array ( '(18|eighteen)', "18" ),
          array ( '(19|nineteen)', "19" ),
          array ( '(20|twenty)', "20" ),
          array ( '(as|so) many', 'asmany' ),
          ),
       self::LINETYPE => array (
         'angled',  'dovetailed',  'escartelly',  'indented',   
         'invected', 'nowy', 'plain', 'potenty', 'raguly',     
          array ('(battled|double) (e?m?battled|crenn?ell?e?y?)',                       'battled-embattled' ),  // two levels of battlements, on upper surface only
          array ('(em)?battled grady',                                                  'battled-embattled' ),
          array ('(em)?battled brett?ess?e?y?',                                         'battled-brettesse' ),                // both sides, same pattern
          array ('(e?m?battled|crenn?ell?e?y?) counter (e?m?battled|crenn?ell?e?y?)',   'battled-counter'  ), // both sides, opposite pattern
          array ('?super (e?m?battled|crenn?ell?e?y?)',                                 'embattled'     ),        // top only
          array ('?super crenellated',                                 'embattled'     ),        // top only
          array ('(e?m?battled|crenn?ell?e?y?) arrondi',                                'embattled-arrondi'     ),           // top only, round crenelles
          array ('(en)?arch(y|ed)',                         'arched'  ),
          array ('concave',                         'arched'  ),
          array ('bevill?ed',                           'bevilled'     ),
          array ('bevill?y',                            'bevilled'     ),
          array ('dau?ncett[ey]) flor(y|etty)',         'dancetty-floretty' , ),
          array ('dau?ncetty',                          'dancetty'         ),
          array ('(nebul[ey]|nuance)',                           'nebuly'         ),
          array ('dantelle',                          'dancetty'         ),
          array ('[ie]ngr(ele|ailed)',                          'engrailed'         ),
          array ('double (en)?arched',                  'double-arched'  ),
          array ('(en)?arched double',                  'double-arched'  ),
          array ('(rayonny|radiant)',                   'rayonny'        ),
          array ('(wavy|[ou]nd[ey]|aiguise)',                 'wavy'      ),
          array ('(urdy|urde|champaine|champion)',      'urdy' ,  ),
          array ('fir twiggy?e?d?',                     'twigged' , ),
          ),
        self::ORIENTATION => array ( 
           'sinister', 'reversed','dexter', 'inverted', 'enhanced', 
           array ( '(abased|abaisse)', 'abased', ),
           array ( '(rompu|fracted)', 'fracted' ),
          ),
        self::ORDINARY => array ( 
            array( 'bars?', 'bar' ),
            array( 'barrulets?', 'barrulet' ),
            array( 'bendlets?', 'bendlet' ),
            array( 'e?sca[rf]pes?', 'bendlet' ),
            array( 'chevronels?', 'chevronel' ),
            array( 'couple closes?', 'couple-close' ), 
            array( 'closets?', 'closet' ),
            array( '(baston|riband)', 'riband' ), // TODO draw this
            array( '[ie]ndorses?', 'endorse' ),
            array( 'humets?', 'humet' ),
            array( 'pall?ets?', 'palet' ),
            array( 'piles? ?of ?(3|three) ?points ?issuing ?from ?the ?chief', 'pile' ),
            array( 'base', 'base' ),
            array( 'bends?', 'bend' ),
            array( 'chief', 'chief' ),
            array( 'fesse?', 'fess' ),
            array( 'ford', 'ford' ),
            array( 'gore', 'gore' ),
            array( 'pale', 'pale' ),
            array( 'point', 'point' ), // TODO draw this - see meaning 2 parker/point
            array( 'ecclesiastical pale', 'pale-ecclesiastical' ),
            array( 'canadian pale', 'pale-canadian' ), // TODO draw this
            array( 'quarter', 'quarter' ),
            array( 'tierce', 'tierce' ),
            array( '(gorge|whirlpool|gurges)', 'gorge' ),
            array( 'grid', 'grid' ),
            array( 'dexter (bas?ton|battoon|batune) ?couped', 'baton-dexter' ),
            array( '(bas?ton|battoon|batune) dexter ?couped', 'baton-dexter' ),
            array( '(bas?ton|battoon|batune) ?sinister ?couped', 'baton' ),
            array( 'bordure', 'bordure' ),
            array( 'cantons?', 'canton' ),
            array( 'double trea?s?sure', 'double-tressure' ),
            array( 'fillet', 'fillet' ),
            array( 'flau?nche?s?', 'flaunch' ),
            array( '(voider|flank|flanque|flasque)s?', 'flaunch' ),
            array( 'grafts?', 'graft' ),
            array( 'gussets?', 'gusset' ),
            array( 'gyrons?', 'gyron' ),
            array( '?based e?s?quie?r?res?', 'gyron' ),
            array( 'inescut?cheon', 'inescutcheon' ),
            array( 'orle', 'orle' ),
            array( 'pall', 'pall' ),
            array( '(shake|hay)fork', 'shakefork' ),
            array( 'pale furche', 'shakefork' ),
            array( 'square flau?nche?s?', 'square-flaunch' ),
            array( 'square (flanks?|flanques?|flasques?)', 'square-flaunch' ),
            array( '?royal trea?s?sure', 'tressure' ),
          ),
        self::ORDINARY_PREFIX => array ( // can be before (and after) ordinary
            'sinister', 'reversed', 'dexter', 'inverted', 
            array ( '(hause|enhanced)', 'enhanced' ),     
            array ( '(abased|abaisse)', 'abased', ),
            array ( '(rompu|fracted)', 'fracted' ),
            array ( '(debrui|depres|oppres)sed (with|by|of)', 'depressed' ),
            array ( 'false', 'voided' ),
          ),
        self::COLOUR_MODS => array (
           array ( '(compony|gobone|gobonated)', 'compony1' ), 
           array ( 'counter (compony|gobone|gobonated)', 'compony2' ),
           array ( '(fimbriated|edged)', 'fimbriated'  ),
           ),
        self::LINETYPE_PREFIX => array (
           array ( 'the (dexter|first|1st|upper|higher) ?(one|1)', 'barmod-up' ),
           array ( 'the (sinister|last|lower|lowest) ?(one|1)','barmod-down' ),  
           array ( 'the (inner|inside) ?ones?',  'barmod-in' ),
           array ( 'the (outer|outside) ?ones?', 'barmod-out' ),
           ),  
        self::LINETYPE_POSTFIX => array (
          array ( '(at|on) ?the top', 'top-only' ),
          array ( '(at|on) ?the bottom', 'bottom-only' ),
           ),
        self::ORDINARY_MODS => array ( // only come after ordinary
          'closetted',
           array ( '[ie]narched', 'inarched' ),                   
           array ( '(couped|humetty|alese)', 'couped' ),                   
           array ( '(couped|humetty|alese) ?in sinister', 'couped-sinister' ),
           array ( '(couped|humetty|alese) ?in dexter', 'couped-dexter' ),
           array ( '(couped|humetty|alese) ?in chief', 'couped-chief' ),
           array ( '(couped|humetty|alese) ?in base', 'couped-base' ), 
           array ( 'pointed', 'pointed' ),                   
           array ( 'pointed ?in sinister', 'pointed-sinister' ),
           array ( 'pointed ?in dexter', 'pointed-dexter' ),
           array ( 'pointed ?in chief', 'pointed-chief' ),
           array ( 'pointed ?in base', 'pointed-base' ), 
           array ( '(bra[zc]ed|interlaced)', 'braced' ),
           array ( '(gemm?ell?(s|ed)?|voided)', 'gemel' ), 
           array ( 'double dancetty', 'fracted' ), 
           array ( 'bott?onn?(ee|y)', 'botonny' ), 
           // array ( 'of # points', 'points' ), // only if label is a ordinary
           array ( '(de)?bruised|fracted|disjoint ?at ?the ?top', 'debruised' ),
           array ( 'en(aluron|urney|toire|toyre)', 'entoire' ),
           'lozengy', 'triangular', 'throughout', 'of pretence',
           ),
        self::COTTICE_MODS => array ( 
           array ( '(cott?ised|cott?iced|endorsed|addorsed|cost)', '1',  ),
           array ( 'double cott?i[sc]ed', '2',  ),
           array ( '(triple|treble) cott?i[sc]ed', '3',  ),
           ),
        self::COTTICE => array ( array ( 'cott?ices?', 'cottice') ),
        self::VOIDED => array ( 'voided' ),
        self::LINETYPE => array ( 
          'angled', 'indented', 'nebuly', 'nowy', 'plain', 'potenty',
          'raguly', 'dovetailed', 'engrailed', 'escartelly',
          array ( '(battled|double) (e?m?battled|crenn?ell?e?y?)', 'battled-embattled' ),  // two levels of battlements, on upper surface only
          array ( '(em)?battled grady', 'battled-embattled'  ),
          array ( '(em)?battled brett?ess?e?y?', 'battled-brettesse'  ),                // both sides, same pattern
          array ( '(e?m?battled|crenn?ell?e?y?) counter (e?m?battled|crenn?ell?e?y?)', 'battled-counter'  ), // both sides, opposite pattern
          array ( '?super (e?m?battled|crenn?ell?e?y?)','embattled'  ),        // top only
          array ( '(e?m?battled|crenn?ell?e?y?) arrondi', 'embattled-arrondi' ),           // top only, round crenelles
          array ( 'invec[kt]ed', 'invected' ),
          array ( '(en)?arched', 'arched' ),
          array ( 'bevill?ed', 'bevilled' ),
          array ( 'bevill?y', 'bevilled' ),
          array ( 'dau?ncett(e|y) flor(y|etty)', 'dancetty-floretty' ),
          array ( 'dau?ncetty', 'dancetty' ),
          array ( 'double (en)?arched', 'double-arched' ),
          array ( '(en)?arched double', 'double-arched' ),
          array ( '(rayonny|rayonated|radiant)', 'rayonny' ),
          array ( '(wavy|undy)', 'wavy' ),
          array ( '(urdy|urde|champaine|champion)','urdy' ),
          array ( 'fir twiggy?e?d?', 'twigged' ),
          ),
      self::ORDINARY_OR_CHARGE => array ( // can distinguish by number (perhaps!)
          array( '?(plain|holy) cross(es)? ?passant', 'cross/plain-cross' ),
          array( 'chevrons?', 'geometric/chevron' ),
          array( 'chevron(el)?s? couched', 'geometric/chevron-couched' ),
          array( 'frets?', 'geometric/fret' ),
          array( 'salta?ires?', 'geometric/saltire' ),
        ),
      self::ORDINARY_NOT_CHARGE => array ( // ordinaries that can be confused with charges
          array( 'cross ?double parted ?and fretty', 'cross-2fretty' ), 
          array( 'cross tripartite ?and fretty', 'cross-3fretty' ), 
          array( 'cross formy throughout', 'cross-formy' ), 
          array( 'cross quarter pierced', 'cross-pierced' ), 
          array( 'fillet cross', 'fillet-cross' ), 
          array( 'cross fillet', 'fillet-cross' ), 
          array( 'frets? couped', 'fret-couped' ), 
        ),
      self::ARRANGEMENT => array (
          array ( 'in ?the pale',               'inpale',        ),
          array ( 'in ?the pale throughout',    'inpalethrough', ),
          array ( 'in ?the pall' ,              'inpall',        ),
          array ( 'in ?the fesse? !point' ,     'infess',        ),
          array ( 'in ?the fesse? throughout' , 'infessthrough', ),
          array ( 'in ?the bend sinister' ,     'inbendsin',     ),
          array ( 'in ?the bend ?dexter' ,      'inbend',        ),
          array ( 'in ?the chevron' ,           'inchevron',     ),
          array ( 'in ?the pile'  ,             'inpile',        ),
          array ( 'in ?an orle'  ,              'inorle',        ),
          array ( 'in ?the orle'   ,            'inorle',        ),
          array ( 'in ?the salti(er|re)' ,           'insaltire',     ),
          array ( 'salti(er|re)w(ays|ise)' ,           'insaltire',     ),
          array ( 'salti(er|re) w(ays|ise)' ,           'insaltire',     ),
          array ( 'in ?the cross'  ,            'incross',       ),
          array ( '?in counter passant' ,     'counter-passant'  ),
          array ( 'pilewise'      ,             'pilewise',      ),
          array ( '?in bar(wise|ways)?'  ,        'inbar',         ),
          array ( 'in ?the chief throughout' ,  'inchiefthrough',),
          array ( 'in ?a quadrangle'   ,        'quadrangle',    ),
          array ( 'chevronwise'   ,        'chevronwise',    ),
          array ( 'in point'   ,        'pilewise',    ),
          array ( 'in triangle'   ,        'triangle',    ),
        ),
      self::SPECIFIER => array (
          array ( '(first|1st)', 'first' ),
          array ( '(second|2nd)', 'second' ),
          array ( '(third|3rd)', 'third' ),
          array ( '(fourth|4th)', 'fourth' ),
          array ( '?each dexter', 'dexter' ),
          array ( '?each sinister', 'sinister' ),
          array ( '(each|every|all|both) ?of ?the', 'each' ),
          array ( 'middle', 'middle' ),
          ),
      self::LOCATION => array (
         array ( 'chief ?point', 'chief' ),
         array ( 'base ?point', 'base' ),
         array ( 'honou?r point', 'honpoint' ),
         array ( 'fesse? point', 'fesspoint' ),
         array ( 'navel point', 'nombril' ),
         array ( 'nombril', 'nombril' ),
         array ( '(flanks?|flaunche?s?)', 'flank' ),
         array ( '(abisme|abyss)', 'abyss' ),
          ),
        self::QUANTIFIER => array (
          array ( 'quarters?', 'quarter' ),
          array ( '(half|section|part)', 'all' ),
          ),
        self::CHARGE_ADJACENT => array (
          array ( '(between|betwixt|inter) ?them', 'between' ),
          array ( 'within ?(them|it)', 'within' ),
          array ( 'above ?(them|it)',  'above' ),
          array ( 'below ?(them|it)',  'below' ),  
          array ( 'with ?(them|it)',   'below' ),
          ),
      );
    include "charge.inc";
    include "chargemod.inc";
    }
  }
   
?>
